Repository navigation
Conversation
debugValue(name) is debugFlag's non-boolean sibling: ?quality= on the web, TN_DEBUG_QUALITY on a native launch. The four ctx members an author searches for (assets.memo, startup.progress, after, beforeRender) are interface properties, so walking exports never found them; they now live in scripts/ctx-capabilities.ts, the same hand-authored registry the render-chain config keys use. Manifest gains 5 rows: 571 entries, pnpm capabilities:check fresh.
…e call trackHotCallbacks treats a non-static update, fixedUpdate, tick or step on any class as per-frame, so the three hot-callback rules reach a game's own entity classes; 12 real sites in 9 kits, 0 false positives. src/quality/reinventions.ts is a data table of the six hand-written forms a shipped capability already covers, fed to no-restricted-syntax. Each row's capability is resolved against capabilities.json or three by the spec, so a message cannot name a removed symbol.
109 hand-written forms replaced across the 16 kits: 38 inline smoothsteps, 23 exponential damp factors, 34 PRNG copies, 3 location.search launch seams. The LCG copies were the engine's own sequence and produce identical values through createRandom; the authored mulberry32 streams (adventure level, kart course, rts world, rain storm) keep a described suppression because swapping them builds different content. Scaffold pins re-recorded; scaffold spec 79 passed. PRD-872 ticks carry their proof; the two sandbox boxes stay open (separate checkout).
A key whose value is Object.is-equal to the current one does not enter pending, so a frame that changed nothing publishes nothing and flush stays quiet. Four kits carried the comparison by hand (starter's 11 fields, action-rpg's 12, tower-defense's sameState, runner's five) and the store now owns it; runner floors distance where the HUD always did, so a fractional odometer cannot republish every frame. state.spec.ts: 3 new cases, red on the previous store (2 failed).
…uns on every kit Review findings from the fresh Opus pass: - A kit's src/render/ may not import a core symbol outside RENDER_PORTABLE_CORE_SYMBOLS, so the six clouds copies, collectathon's paint tables, platformer's decoration, snow's scenery and the shooter and tower-defense shape streams go back to their own generators, and the PRNG row excludes src/render/** (it still covers a level, an entity, a scene). check-core-boundary passes again; it failed on 13 render files. - LockOn updates the target's whole world-matrix chain once per frame; a leaf-only update left the reticle one frame behind. - The damp row requires the literal 1 on the left, so a fog factor cannot match; the matrix row's message names markStatic for a single static node. - The kit-wide gate is now a spec: all 16 templates/*/src trees linted with the hot rules and the six rows at error, failing closed under 300 files. It found two suppressions that had gone unused and would have failed a generated game's pnpm lint. - PRD claims corrected: check-template-quality does not run ESLint, the render PRNG revert, the playtest run's environmental failures, and the 4 measured kit changed-only checks (not 5). state.spec.ts 9 passed, quality-rules 18 passed (incl. the kit gate), scaffold 79 passed, capabilities fresh, ci:fast pass.
Second review: the widened world-matrix update was not the cause of the one-frame trail — the frame order was. lock.update runs before the hero reads its target, while the creatures it frames move later in the same frame, so bounds and reticle were always a pose behind. LockOn.update keeps the selection; place(camera, dt) owns the bounds and the reticle and runs after warden, mosslings, foes and dummies have moved. PRD counts corrected to what git grep measures (38 smoothstep, 24 damp calls from 22 expressions, 3 launch seams, 3 LCGs), and the 873 proof names the four kits that changed.
jonit-dev
marked this pull request as ready for review
November 11, 2026 05:47
The fresh shooter scaffold passes typecheck, the new lint and format; the remaining failures are the software adapter (kit-contract engine-cost, a playtest-worker RangeError) and cold asset cooking. The CI board carries the playtest proof.
…the engine seam CI's unit lane found the two places the rows changed a contract: - rts/src/sim/terrain.ts imported MathUtils from three for the smoothstep, and rts-runtime-cost.spec asserts a sim module imports no three. The inline form returns with a described suppression naming that spec. - rain's GameUi reads the engine's debugValue seam now, and the unit test stubbed only window.location; a browser's window.location is the same object as globalThis.location, so the stub shares one object and the URL tier test exercises the real path again. quality-rules 18, rain-quality 10, rts-runtime-cost 8, scaffold 79: pass.
With the GPU idle the branch passes adventure, collectathon, kart, puzzle and snow outright; the remaining rows either also fail on origin/develop in the same environment (platformer sight line, shooter worker RangeError) or are frame-cost rows under a CPU load of 9-13 from other agents. action-rpg's restart row is green when run alone. No green sweep, so the box stays open.
Only the starter scaffold pin conflicted; every pin is recomputed from the merged tree in the commit that follows.
develop's starter kit change and this branch's both land in the tree the pin hashes; 16 kits, 1 moved. quality-rules 18, scaffold 79, rain-quality 10, rts-runtime-cost 8, state 9, engine-mcp search 108, typecheck and ci:fast pass on the merge.
Pins recomputed from the merged tree in the next commit.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
One PR for the whole absorb batch, as asked. It carries PRD-872 end to end in this repository, plus PRD-873's store change.
ObjectPool, theRigidBody3Drest options, theprewarmrestore and all of PRD-874 are open — the reasons are below the landed work.Review: fresh Opus 5.5 at high effort (Claude Code), verdict BLOCK → fixed
The first pass returned BLOCK with two findings. Both are fixed in
b29aca3af, and the reviewer's non-blocking notes are addressed or recorded:createRandomimported into 13 kitsrc/render/files;check-core-boundaryfails (runs inbudgetsand CI)RENDER_PORTABLE_CORE_SYMBOLS. The 13 files keep their own generators and the PRNG row excludessrc/render/**; the boundary check passes. The row still covers a level, an entity, a scene, a sim.updateWorldMatrixleft the target's root/groups a frame behindtarget.mesh.updateWorldMatrix(true, true)once per frameX - Math.exp(…)1on the leftmarkStatic(node)as well asrenderer.matrixWorldquality-rules.spec.ts: all 16templates/*/srctrees under the hot rules + the six rows aterror, failing closed under 300 files. It found two suppressions that had gone unused and would have failed a generated game's lint.Math.random, the LCG pair and0x6d2b79f5failing separatelyInputMap.prototype.axisanddebugValueexistcheck-template-qualitydoes not run ESLint, the render PRNG revert, the playtest result, and the measured 4 kit changed-only checks (the survey said 5)Recorded, not fixed:
state.setcomparesObject.is, so0/-0now publishes (documented in the store's JSDoc);racingmutateslastOnRoadin place and publishes because sibling keys change (the documented catch);?still=0now means off, which is the engine's one launch vocabulary.Landed
PRD-872 — the lint names the engine call
trackHotCallbackstreats a non-staticupdate/fixedUpdate/tick/stepon any class as per-frame. 12 real sites in 9 kits, 0 false positives. Fixes: 9touch-controls.tsfiles reuse oneknobPosition;Warden.updatereusestoHero;LockOn.updatecaches the target's mesh list and the reticle box.src/quality/reinventions.ts(6 rows → ESLint'sno-restricted-syntax), each row'scapabilityresolved against the manifest orthree. 109 sites replaced outsidesrc/render/: launch seams (debugFlag/debugValue), 23 damp factors, 38 smoothsteps.debugValue(name)exported from core.ctx.assets.memo,ctx.startup.progress,ctx.after,ctx.beforeRenderhave manifest rows (scripts/ctx-capabilities.ts, the render-chain registry pattern; interface-member JSDoc is not indexed), 571 fresh entries; the four search queries return them.debugValueis indexed from its JSDoc.PRD-873 — the engine owns the pool and the body's rest (partial)
Object.is-equal to the current one no longer enterspending, so a frame that changed nothing publishes nothing. The 4 hand-written changed-only checks are deleted (starter11 fields,action-rpg12,tower-defense'ssameState,runner5);runnerfloorsdistance, which the HUD always did. 3 new spec cases, red on the previous store.Open, and why
starlance,midway-open-pacific,stress-labare a separate checkout. Not run, not claimed.ObjectPool,RigidBody3Drest options,prewarmrestore: open. The pool changes the draw path and owes a visual judge; the body options need the Rust physics crate and a native build/desktop playtest in the same commit; theprewarmrestore changes renderer semantics and needs the GPU harness. None of those could be proven here.pnpm test:templateswas run afternode scripts/build-wasm.mjs(which clearedTN_PACK_WEB_ENGINE_STALE). It fails for environment reasons: 8 kitsTN_PLAYTEST_PERF_FEW_GPU_SAMPLES(software adapter), 6 templates' dev servers miss the 15 s readiness window while cooking KTX2, 2TN_PLAYTEST_ENGINE_COST_OVER_BOUNDunder software. No green playtest is claimed.Gates actually run (this head)
pnpm exec vitest run packages/create-threenative/__tests__/quality-rules.spec.tspnpm exec vitest run packages/core/__tests__/state.spec.tspnpm exec vitest run packages/create-threenative/__tests__/scaffold.spec.tspnpm exec vitest run packages/engine-mcp/__tests__/search.spec.tspnpm typecheckpnpm exec tsx scripts/check-core-boundary.tspnpm capabilities:checkpnpm api:surface:checkpnpm check:docspnpm ci:fastpnpm test:templatesSecond review pass (Opus 5.5 high): one finding left, fixed in
7d057342cFinding 1 (boundary) verified fixed. The re-review showed the lock-on lag was frame order, not the matrix update:
lock.updateruns before the hero reads its target, while the creatures it frames move later in the same frame.LockOn.updatenow keeps only the selection;place(camera, dt)owns the bounds and the reticle and runs after the warden, mosslings, foes and dummies have moved (adventure/src/scenes/Play.ts:778).git grepmeasures: 38 smoothstep expressions, 24 damp calls from 22 expressions, 3 launch seams, 3 LCGs outsidesrc/render/; 2 suppressions remain (adventure level, rts replay).starter, action-rpg, tower-defense, runner).Remaining caveat from the re-review, recorded not hidden: the kit-wide spec applies the three hot rules and the six reinvention rows, not the full shipped
qualityConfig(typed rules, react-hooks,startup-override-reason), so it does not by itself prove a generated game's wholepnpm lintis green.Capability discovery: every abstraction this branch adds is searchable and resolvable
Checked against the built manifest through the MCP search code (
searchCapabilities+capabilityDetail):ctx.assets.memoctx.startup.progressctx.afterctx.beforeRenderdebugValuecreateRandomInputMappnpm caps:recallexits 0 with the same 7 measured not-owned misses asdevelop(no new misses).pnpm exec vitest run packages/engine-mcp/__tests__/{server,capability-examples,search-gold,search}.spec.ts— 138 passed, including "finds every exact symbol name the manifest exports as the first row" and "type-checks every hand-authored example against the type it demonstrates".Gates run after the capability check
pnpm budgets(hard invariants: workspace pins, native shims, core boundary, capability-docs census,caps:recall, evidence budget, VFX coverage, budgets, generated ctx/reference tables, realism docs/conformance/matrix, capability duplicates, template quality)pnpm caps:recallpnpm exec vitest run packages/engine-mcp/__tests__/{server,capability-examples,search-gold}.spec.tspnpm testunder Node 20.19.6 (the versionprocedural-animalsrequires; the shell default is 22)@threenative/runtime-native; 19/19 and 46/46 in the last two packages, no failurepnpm test@threenative/runtime-nativeTN_PUMP_PROBE_NO_BINARY— the desktop host is not built (pnpm native:buildis opt-in). Node 22 additionally failsprocedural-animalswithTN_ANIMAL_BUILD_RUNTIME; under Node 20 that package is 166/166CI on
92b2749fe: greenRun 42970102867 —
Change scope,ci-required,lint,supply-chain,budgets,build-artifacts,typecheck,test,test-unit (1/1),golden-path,golden-path-template (action-rpg)all pass. The first ready-for-review run caught two real regressions from the rows, both fixed in92b2749fe:rts/src/sim/terrain.tsimportedMathUtilsfromthree, andrts-runtime-cost.specasserts a sim module imports nothree; the inline form returns with a described suppression naming that spec.rain'sGameUireads the engine'sdebugValueseam, and the unit test stubbed onlywindow.location; the stub now shares one object withglobalThis.location, so the URL-tier test exercises the real path.GPU retry on the branch (
5f0e37694)Run from a private worktree of this branch, Node 20, GPU idle (RTX 2080),
TN_PLAYTEST_ALLOW_SOFTWAREunset:adventure,collectathon,kart,puzzle,snow.origin/developin the same environment (platformersight line,shooterworkerRangeError: Offset is outside the bounds of the DataView) and frame-cost rows under a CPU load of 8–13 from other agents sharing this machine (no-hitchfew-GPU-samples,engine-costover 16.7 ms).action-rpg restart-resetsfailed once in the sweep and is green when run alone.performance-regression.yml), not on the PR board.5f0e37694(the PRD-evidence commit) is green on run 43091324878 after one flake rerun:golden-path-template (action-rpg)failed at./scaffold.sh action-rpg(2 s, no output) and the rerun of the same commit passed.Merged
origin/develop(b01de92c7)starter's scaffold pin; recomputed from the merged tree (16 kits, 1 moved).pnpm typecheckclean ·pnpm ci:fastpass ·pnpm budgetspass (hard invariants, capability census, duplicates, generated tables, core boundary, template quality) ·capabilities:checkfresh (571) ·api:surface:checkok · quality-rules 18 · scaffold 79 · rain-quality 10 · rts-runtime-cost 8 · state 9 · engine-mcp search 108.7a2c03d17): three pushes produced 0 runs and 0 check-runs for the branch, and the manualworkflow_dispatchonabsorb-2026-11-10was cancelled. Repo-wide, onlyCI janitorruns appeared in that window. Until Actions creates a run, the PR cannot showci-requiredgreen; the merge itself is validated locally above.Second merge:
origin/developatc1c25a657(main promotion merge)Pushed as
3d4644799. Conflict again only thestarterscaffold pin; every pin recomputed (16 kits moved — a shared input changed in develop). On the merged tree:pnpm typecheckclean,ci:fastpass,capabilities:checkfresh,api:surface:checkok, quality-rules/scaffold/state/rain/rts 124 passed, engine-mcp search 109 passed, kit-wide lint gate green.CI on the merge (
43152340235) is red only for items that are already red onorigin/develop's own tree, each verified against develop itself:check-budgets: "native coverage report is stale: source digest changed toaa2574…"develop(ba9df86d4)capability-manifest.spec: alias corpus 59 vs 53developcommitgame.spec:input.vector("move")returns[0.401, 0.2007]not[0.5, 0.25]git diff origin/developtouches no input codetemplate.spec:action-rpg1231 /starter1234 words, limit 1200Nothing in that list is this branch's code, and each fix belongs on
develop(the alias one is already staged there).